import api from '@/odoojs/index.js'

import { inject, watch, computed, reactive, ref, toRaw } from 'vue'

function sleep(millisecond) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve()
    }, millisecond)
  })
}

export function useFormView(props) {
  const lang = inject('lang')

  const localState = {
    model: undefined,
    formview: undefined,
    editmodel: undefined
  }
  const state = reactive({
    sheet: {},
    metadata: {},
    record: {},
    data_changed: 0,

    editable: false,
    values: {},
    record_display: {}
  })

  function view_get() {
    // check_lang()
    return localState.formview
  }

  const buttons = computed(() => {
    const view = view_get(state.data_changed)
    if (view) {
      return view.buttons
    } else {
      return {}
    }
  })

  // watch lang actionId resId
  watch(
    () => [lang.value, props.actionId, props.resId],
    async (newVal, oldVal) => {
      console.log('watch lang actionId', newVal, oldVal)
      if (newVal) {
        const [lang, actionId, resId] = newVal
        if (lang && actionId) {
          // console.log('lang', newVal, oldVal, props.actionId)
          load_action(actionId, resId)
        }
      }
    },
    { immediate: true }
  )

  async function load_action(action_id, resId) {
    const act = api.action(action_id)
    // console.log(act)

    state.metadata = await act.load_metadata({
      callback: res => {
        state.metadata = res
        // console.log(datastore)
      }
    })
    console.log('load_metadata ', state.metadata)

    const formview = act.form
    localState.formview = formview
    localState.model = formview.model

    state.sheet = formview.get_arch_sheet()
    // console.log('formview sheet', state.sheet)

    if (resId) {
      const rid = Number(props.resId)
      state.record = await formview.load_data(rid)
      state.data_changed += 1
      state.editable = false
      state.sheet = formview.get_arch_sheet({
        editable: state.editable,
        record: state.record,
        values: state.values
      })
    } else {
      const editmodel = formview.new_editmodel()
      localState.editmodel = editmodel

      const result = await editmodel.onchange()
      // console.log('onchange', result)

      const { record_display, values, domain } = result

      state.record_display = { ...record_display }
      state.values = { ...values }
      state.data_changed += 1
      state.editable = true
      state.sheet = formview.get_arch_sheet({
        editable: state.editable,
        record: state.record,
        values: state.values
      })
    }
  }

  async function onChange(fname, value) {
    console.log('onChange in formview', fname, value)
    const view = view_get()
    if (!view) return

    const editmodel = localState.editmodel
    if (!editmodel) return

    const result = await editmodel.onchange(fname, value)
    // console.log('onchange', result)

    const { record_display, values, domain } = result

    state.record_display = { ...record_display }
    state.values = { ...values }

    state.sheet = view.get_arch_sheet({
      editable: state.editable,
      record: state.record,
      values: state.values
    })

    // onchange 使用 form 自身的校验, 仅仅校验刚刚编辑的字段
    // 无需全部校验
    // 在提交时, 应做一次校验
    // ctx.editRef.value.validate()
  }

  async function handelCommit(validate) {
    const view = view_get()
    if (!view) return

    const editmodel = localState.editmodel
    if (!editmodel) return

    const id_ret = await editmodel.commit(async done => {
      await sleep(100)
      // 在提交函数中执行 校验.
      // 提交函数 会进行排队. 等待 以前的 onchange 全部完成.
      // 以确保 当前页面中的 数据是 onchange 后的最新数据
      // 这里再等待100ms 是为了确保 前端页面完全刷新

      if (validate) {
        validate(done)
      }

      // ctx.editRef.value.validate().then(
      //   () => done(true),
      //   () => done(false)
      // )
    })

    console.log(id_ret)

    if (id_ret) {
      if (props.resId) {
        state.editable = false
        // state.record = await view.load_data(id_ret)
        const record = await view.load_data(id_ret)
        state.record = record
        state.values = {}
        state.sheet = view.get_arch_sheet({
          record: state.record,
          values: state.values
        })
        state.data_changed += 1
      } else {
        return id_ret
        // const rounteVal = ctx.router.currentRoute.value
        // const { query, path } = rounteVal
        // const { menu } = query
        // const query2 = { menu, view_type: 'form', id: id_ret }
        // ctx.router.push({ path, query: query2 })
      }
    } else {
      // 校验失败
    }
  }

  function onClickEdit() {
    const view = view_get()
    if (!view) return

    const editmodel = view.new_editmodel()
    localState.editmodel = editmodel

    state.record_display = editmodel.set_edit({ record: state.record })
    // state.record_edit = { ...state.record_display }
    state.values = {}
    state.editable = true
    state.sheet = view.get_arch_sheet({
      editable: state.editable,
      record: state.record,
      values: state.values
    })
  }

  function onClickCancel() {
    if (props.resId) {
      state.editable = false
      localState.editmodel = undefined
      state.record_display = {}
      // state.record_edit = {}
      state.values = {}
      const view = view_get()
      if (!view) return
      state.sheet = view.get_arch_sheet({
        editable: state.editable,
        record: state.record,
        values: state.values
      })

      return
    } else {
      // // 新增页面 , 点击取消, 返回列表页面

      return true
    }
  }
  function onClickSave(...args) {
    //   console.log('onclickSubmit')

    return handelCommit(...args)
  }

  async function onClickDel() {
    const view = view_get()
    if (!view) return

    await view.unlink(state.record.id)

    return true
  }

  function onClickCRUD(btn, ...args) {
    console.log(btn)
    const btn_fns = {
      // new: onClickNew,
      edit: onClickEdit,
      save: onClickSave,
      cancel: onClickCancel,
      del: onClickDel
      // //
      // archive: onArchive,
      // unarchive: onUnarchive,
      // copy: 'handleOnCopy',
      // unlink: 'onClickDel',
      // unlink_multi: '',
      // export: 'handleOnExport'
    }

    return btn_fns[btn](...args)
  }

  const formInfo = computed(() => {
    // localState.formview = formview
    const info = {
      model: localState.model,
      metadata: toRaw(state.metadata),

      record: state.editable
        ? toRaw(state.record_display)
        : toRaw(state.record),
      record_readonly: toRaw(state.record),
      values: toRaw(state.values),
      editable: toRaw(state.editable)
    }

    return { ...info }
  })

  const record_edit = computed({
    get() {
      return state.record_display
    },
    set(val) {
      console.log(val)
      //
    }
  })

  return {
    buttons,
    record_edit,
    formInfo,
    sheet: computed(() => state.sheet),
    onChange,
    onClickCRUD
  }
}
